<?php

namespace App\Http\Controllers\Admin;
use App\DTOS\Admin\PayOrderDTO;
use App\DTOS\NeiGouDTO;
use App\Exceptions\ServiceException;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Game\GameChannel;
use App\Models\Game\GameGoods;
use App\Models\Game\GameMallGoods;
use App\Models\Game\GamePackage;
use App\Models\Game\PayOrder;
use App\Models\Game\Server;
use App\Models\Game\ServerGroup;
use App\Models\Game\UserMember;
use App\Models\Game\UserRole;
use App\Services\Game\DouyinService;
use App\Services\Game\NeigouService;
use App\Services\Game\PayOrderService;
use App\Services\Game\QzlService;
use App\Services\Game\UserMemberService;
use App\Services\Game\UserRoleService;
use App\Utils\InitUtils;
use App\Utils\MyLog;
use App\Utils\ResponseUtil;
use Carbon\Carbon;
use Illuminate\Broadcasting\Channel;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use PHPUnit\TextUI\XmlConfiguration\Group;


class PayOrderController extends Controller
{
    private NeigouService $neigouService;
    private PayOrderService $payOrderService;
    private DouyinService $douyinService;
    private QzlService $qzlService;
    private UserRoleService $userRoleService;
    private UserMemberService $userMemberService;

    /**
     * PayOrderController constructor.
     * @param NeigouService $neigouService
     * @param PayOrderService $payOrderService
     * @param DouyinService $douyinService
     * @param QzlService $qzlService
     * @param UserRoleService $userRoleService
     * @param UserMemberService $userMemberService
     */
    public function __construct
    (
        NeigouService $neigouService,PayOrderService $payOrderService,
        DouyinService $douyinService,QzlService $qzlService,
        UserRoleService $userRoleService,UserMemberService $userMemberService

    )
    {
        $this->neigouService = $neigouService;
        $this->payOrderService = $payOrderService;
        $this->douyinService = $douyinService;
        $this->qzlService = $qzlService;
        $this->userRoleService = $userRoleService;
        $this->userMemberService = $userMemberService;
    }

    public function paginate()
    {
        $invite_code = request()->get('invite_code');
        $gamechannel = request()->get('gamechannel');
        $model = request()->get('model');
        $serverPackage = request()->get('serverPackage');
        $packageArray = explode(',', $serverPackage); // 将字符串转换为数组
        $serverPackage1 = request()->get('serverPackage1');
        $packageArray1 = explode(',', $serverPackage1); // 将字符串转换为数组



        $payOrderSearchDTO = new PayOrderDTO(request()->all());
        //如果只传入服务器分组信息,查出默认分组的服务器ID组成数组
        $serverGroup= $payOrderSearchDTO->getServerGroup();
        $gameArea= $payOrderSearchDTO->getGameArea();
        if($serverGroup && $gameArea==null){
            $groupsidsarray = explode(",", $serverGroup);
            $serverids=Server::query()->whereIn('group_id',$groupsidsarray)->pluck('server_id')->toArray();
            MyLog::info('S所选服务器ID分组'.json_encode($serverids));
            $payOrderSearchDTO->setGameAreas($serverids);
        }

        $admin = Auth::guard('admin')->user();
        $permissionIds = $admin->permissions->pluck('id')->toArray();
        $groups_ids = $admin['groups_ids'];
        $groups_ids_array = explode(",", $groups_ids);

        //查看分组渠道名
        $type = ServerGroup::query()
            ->select('type')
            ->whereIn('id', $groups_ids_array)
            ->get()
            ->pluck('type')
            ->toArray();
        MyLog::info('用户的数据分组信息'.json_encode($type));
        if (in_array('qqgame', $type)&& count($type) === 1) {
           $gamechannel=10;//qq渠道
        }
        if (in_array('qingyi', $type)&& count($type) === 1) {
            $gamechannel=12;
        }
        if ($invite_code){
            $customerIds = Customer::query()->where('invite_code',$invite_code)->pluck('id')->toArray();
            $payOrderSearchDTO->setCustomerIds($customerIds);
        }
        if($gamechannel){
            $channel = GameChannel::query()
                ->where("id", $gamechannel)
                ->with('packages')
                ->first();
            MyLog::info('渠道信息'.json_encode($channel));
            $packageIds = $channel->packages->pluck('package_no')->toArray();
            $payOrderSearchDTO->setPackeageNo($packageIds);
            MyLog::info('包号'.json_encode($packageIds));
        }
        if($model)
        {
            $packageNos=GamePackage::query()->where("type",$model)->pluck('package_no')->toArray();
            $payOrderSearchDTO->setPackeageNo($packageNos);
        }
        if($serverPackage)
        {
            $payOrderSearchDTO->setPackeageNo($packageArray);
        }
        if($serverPackage1)
        {
            $payOrderSearchDTO->setPackeageNo($packageArray1);
        }


        $paginate = $this->payOrderService->paginate($payOrderSearchDTO);
        $data = $paginate->items();
        $customerIds = collect($data)->pluck('customer_id')->unique()->toArray();
        $customers = Customer::query()->whereIn('id',$customerIds)->get();
        foreach($data as &$datum){
            $customer = collect($customers)->where('id',data_get($datum,'customer_id'))->first();
            if($customer){
                $customerArr = array_only($customer,['id','phone','package_no']);
                $customerArr['id'] = (string)$customerArr['id'];
                $datum['customer'] = $customerArr;
            }
            $datum['customer_id'] = (string)$datum['customer_id'];
        }
        $res = [];
        $res['code'] = 0;
        $res['count'] = $paginate->total();
        $res['data'] =  $data;
        return ResponseUtil::json($res);
    }

    public function edit($id){
        $refundstatus = request()->get('refund_status'); //维护时间，维护时间到期后，调用API关闭服务器
        $payOrder = PayOrder::query()->where('id', $id)->first();
        if($refundstatus){
            $payOrder->refund_status=$refundstatus;
            $payOrder->save();
        }
    }

    public function export(){
        try {
            $invite_code = request()->get('invite_code');
            $gamechannel = request()->get('gamechannel');
            $payOrderSearchDTO = new PayOrderDTO(request()->all());
            $admin = Auth::guard('admin')->user();
            $permissionIds = $admin->permissions->pluck('id')->toArray();
            $groups_ids = $admin['groups_ids'];
            $groups_ids_array = explode(",", $groups_ids);
            $model = request()->get('model');
            $serverPackage = request()->get('serverPackage');

            $packageArray = explode(',', $serverPackage); // 将字符串转换为数组
            $serverPackage1 = request()->get('serverPackage1');
            $packageArray1 = explode(',', $serverPackage1); // 将字符串转换为数组

            //查看分组渠道名
            $type = ServerGroup::query()
                ->select('type')
                ->whereIn('id', $groups_ids_array)
                ->get()
                ->pluck('type')
                ->toArray();
            MyLog::info('用户的数据分组信息'.json_encode($type));
            if ($type!=null && in_array('qqgame', $type)&& count($type) === 1) {
                $gamechannel=10;//qq渠道
            }
            if ( $type!=null && in_array('qinyi', $type)&& count($type) === 1) {
                $gamechannel=12;//qq渠道
            }
            if ($invite_code){
                $customerIds = Customer::query()->where('invite_code',$invite_code)->pluck('id')->toArray();
                $payOrderSearchDTO->setCustomerIds($customerIds);
            }
            if($gamechannel){
                $channel = GameChannel::query()
                    ->where("id", $gamechannel)
                    ->with('packages')
                    ->first();
                $packageIds = $channel->packages->pluck('package_no')->toArray();
                $payOrderSearchDTO->setPackeageNo($packageIds);
                MyLog::info('包号'.json_encode($packageIds));
            }
            if($model)
            {
                $packageNos=GamePackage::query()->where("type",$model)->pluck('package_no')->toArray();
                $payOrderSearchDTO->setPackeageNo($packageNos);
            }
            if($serverPackage)
            {
                $payOrderSearchDTO->setPackeageNo($packageArray);
            }
            if($serverPackage1)
            {
                $payOrderSearchDTO->setPackeageNo($packageArray1);
            }
            $paginate = $this->payOrderService->paginate($payOrderSearchDTO);
            $data = $paginate->items();
            $customerIds = collect($data)->pluck('customer_id')->unique()->toArray();
            $customers = Customer::query()->whereIn('id',$customerIds)->select(['id','phone','package_no','invite_code'])->get()->toArray();

            $excelRows = [
                ['我司订单号','平台订单号', '长ID','邀请码', '订单名称','详情','订单状态','推送状态','区服编号','角色ID','包号','购买数量','客户端传入价格','真实价格','下单时间']
            ];
            foreach($data as $datum){
                $customer = collect($customers)->where('id',data_get($datum,'customer_id'))->first();
                $excelRows[] = [
                    data_get($datum,'order_no')."\t",
                    data_get($datum,'channel_order_no')."\t",
                     data_get($datum,'customer_id')."\t",
                    data_get($customer,'invite_code'),
                    data_get($datum,'name'),
                    data_get($datum,'detail'),
                    data_get($datum,'status')==1?'已支付':'待支付',
                    $this->getPushStatusName(data_get($datum,'push_status')),
                    data_get($datum,'game_area'),
                    data_get($datum,'role_id'),
                    data_get($customer,'package_no',''),
                    data_get($datum,'number'),
                    data_get($datum,'front_fee') ? data_get($datum,'front_fee') : 0,
                    data_get($datum,'fee') ?data_get($datum,'fee'):0,
                    data_get($datum,'created_at'),
                ];
            }
            $csvContent = arrayToScvContent($excelRows);
            // Content-Disposition
            return ResponseUtil::success(cacheDownload($csvContent,'.充值订单.csv'));

        } catch (\Exception $e){
            return ResponseUtil::error($e->getMessage());
        }
    }

    private function getPushStatusName($pushStatus){
        switch($pushStatus) {
            case 0: return '待推送';
            case 1: return '推送成功';
            case -1: return '推送失败';
        }
        return '';
    }

    public function query($id)
    {
        try {
            $payOrder = PayOrder::query()->find($id);
            if (!$payOrder){
                throw new \Exception("此订单不存在");
            }
            if ($payOrder->status == 1) {
                throw new \Exception("订单已经完成,无需主动查询");
            }
            $orderNo = $payOrder->order_no;
            $prefix = explode("_",$orderNo)[0] ?? '';
            $boolean = false;
            switch($prefix) {
                case 'qzl': //趣智连
                    $boolean = $this->qzlService->query($payOrder);
                    break;
                case 'dy': //抖音支付
                    $boolean = $this->douyinService->query($payOrder);
                    break;
                case 'yiyou'://易游
                    return ResponseUtil::error("易游平台,无法主动查询");
            }
            if ($boolean){
                return ResponseUtil::success();
            } else {
                return ResponseUtil::error('订单未支付');
            }
        } catch(\Exception $e) {
            DB::rollBack();
            return ResponseUtil::error($e->getMessage());
        }
    }

    public function push($id)
    {
        try {
            $payOrder = PayOrder::query()->find($id);
            if ($payOrder->push_status == 1) {
                return ResponseUtil::error("无需重复推送");
            }
            if ($payOrder->status != 1) {
                return ResponseUtil::error("订单未支付,无法推送");
            }

            $goodsId = data_get($payOrder,'goods_id');
            $serverId = data_get($payOrder,'game_area');

            $package_no= data_get($payOrder,'package_no');



            $gameGoods = $this->payOrderService->findConfigIndex($package_no,$goodsId);
            MyLog::info('付款了强推订单返回商品列表'.json_encode($gameGoods));

            //$gameGoods = GameGoods::query()->where('channeltype', 0)->find($goodsId);
            $typeValue = data_get($gameGoods,'price_fee');

            $neiGouDTO = new NeiGouDTO();
            $neiGouDTO->setGameArea($payOrder->game_area);
            $neiGouDTO->setNumber($payOrder->number);
            $neiGouDTO->setRoleId($payOrder->role_id);
            $neiGouDTO->setOrderNo($payOrder->order_no);
            $neiGouDTO->setGoodsId($payOrder->goods_id);
            $neiGouDTO->setTypeValue($typeValue);
            $neiGouDTO->setIsVirtial(0);
            $neiGouDTO->setDiscount(0);
            $this->neigouService->pushToServer($neiGouDTO);

            $payOrder->updated_at = date("Y-m-d H:i:s");
            $payOrder->push_status = 1;
            $payOrder->save();

            return ResponseUtil::success();
        } catch(\Exception $e) {
            DB::rollBack();
            return ResponseUtil::error($e->getMessage());
        }

    }

    public function forcePush($id)
    {
        $payOrder = PayOrder::query()->find($id);
        $payOrder->push_status = 0;
        $payOrder->updated_at = date("Y-m-d H:i:s");
        $payOrder->save();
        return $this->push($id);
    }

    public function nopayForcePush($id){ //未付款,强制推送

        try {
            $payOrder = PayOrder::query()->find($id);
            if ($payOrder->push_status == 1) {
                return ResponseUtil::error("无需重复推送");
            }

            $goodsId = data_get($payOrder,'goods_id');
            $serverId = data_get($payOrder,'game_area');

            $gameGoods = $this->payOrderService->findConfigIndex($serverId,$goodsId);
            MyLog::info('未付款强推订单返回商品列表'.json_encode($gameGoods));
            $typeValue = data_get($gameGoods,'type_value');

            $neiGouDTO = new NeiGouDTO();
            $neiGouDTO->setGameArea($payOrder->game_area);
            $neiGouDTO->setNumber($payOrder->number);
            $neiGouDTO->setRoleId($payOrder->role_id);
            $neiGouDTO->setOrderNo($payOrder->order_no);
            $neiGouDTO->setGoodsId($payOrder->goods_id);
            $neiGouDTO->setTypeValue($typeValue);
            $this->neigouService->pushToServer($neiGouDTO);

            $payOrder->updated_at = date("Y-m-d H:i:s");
            $payOrder->push_status = 1;
            $payOrder->save();

            return ResponseUtil::success();
        } catch(\Exception $e) {
            DB::rollBack();
            return ResponseUtil::error($e->getMessage());
        }

    }

    public function sta(){ //统计金额
        $payTimeBegin = request()->get('payTimeBegin');
        $payTimeEnd = request()->get('payTimeEnd');
        $gameArea = request()->get('gameAreas');
        $channel = request()->get('channel');
        $invite_code = request()->get('invite_code');
        $model = request()->get('model');
        $serverPackage = request()->get('serverPackage');

        $packageArray = explode(',', $serverPackage); // 将字符串转换为数组
        $serverPackage1 = request()->get('serverPackage1');
        $packageArray1 = explode(',', $serverPackage1); // 将字符串转换为数组
        $packageNos=[];
        if($model)
        {
            $packageNos=GamePackage::query()->where("type",$model)->pluck('package_no')->toArray();
        }
        if($serverPackage)
        {
            $packageNos=$packageArray;
        }
        if($serverPackage1)
        {
            $packageNos=$packageArray1;
        }
        $customerIds = null;
        if ($invite_code){
            $customerIds = Customer::query()->where('invite_code',$invite_code)->pluck('id')->toArray();
        }
        $model = PayOrder::query();
        $model->where('status',1);
        //$model->whereRaw('front_fee=fee');
        if ($gameArea!==null){
            // 如果是字符串，拆分为数组
            if (is_string($gameArea)) {
                $gameAreaArray = explode(',', $gameArea); // 将字符串拆分为数组
            } else {
                $gameAreaArray = [$gameArea]; // 如果是单个值，放入数组
            }
            MyLog::info('当前区服数据'.json_encode($gameAreaArray));
            $model->whereIn('game_area',$gameAreaArray);
        }
        if($packageNos){
            $model->whereIn("package_no",$packageNos);
        }
        if ($customerIds!==null){
            $model->whereIn('customer_id',$customerIds);
        }
        if ($customerIds!==null){
            $model->whereIn('customer_id',$customerIds);
        }
        if ($payTimeBegin){
            $model->where("created_at",">=",$payTimeBegin);
        }
        if ($payTimeEnd) {
            $model->where("created_at","<=",$payTimeEnd);
        }
        if ($channel){
            $model->whereRaw("SUBSTRING_INDEX(order_no,'_',1) = ?",[$channel]);
        }
        $sumFee = $model->sum("fee") / 100;
        return ResponseUtil::success(['paySum'=>number_format($sumFee,2)]);
    }


    public  function  report(){//组装报表数据
        $channel = request()->get('channel');
        $channels = explode(',', $channel);

        MyLog::info("查看传入的参数".json_encode(request()->all()));
        $admin = Auth::guard('admin')->user();
        $permissionIds = $admin->permissions->pluck('id')->toArray();
        $groups_ids = $admin['groups_ids'];
        $groups_ids_array = explode(",", $groups_ids);
        MyLog::info('所屬數據權限分組'.json_encode($groups_ids_array));
        //查看分组渠道名
        $type = ServerGroup::query()
            ->select('type')
            ->whereIn('id',$groups_ids_array)
            ->get()
            ->pluck('type')
            ->toArray();
        MyLog::info('所屬渠道類型'.json_encode($type));

        //過濾所屬服務器列表
        $services = Server::query()
            ->whereIn('group_id', $groups_ids_array)
            ->pluck('server_id')
            ->toArray();
        $gameArea = request()->get('gameArea');
        if($gameArea){
            $gameAreas = explode(',', $gameArea);

        }else{
            $gameAreas=$services;
        }
        MyLog::info('服務器列表'.json_encode($gameAreas));
        $gameAreaPlaceholders = array_fill(0, count($gameAreas), '?');

        $payTimeBegin = request()->get('createDateBegin');
        $payTimeEnd = request()->get('createDateEnd');

        if (!$payTimeBegin){
            return ResponseUtil::error("开始时间不能为空");
        }
        if (!$payTimeEnd) {
            return ResponseUtil::error("结束时间不能为空");
        }

        $query = "SELECT DATE(created_at) AS date, SUBSTRING_INDEX(order_no, '_', 1) AS category, SUM(fee) AS fee, SUM(front_fee) AS front_fee, (SUM(front_fee) - SUM(fee)) AS Dvalue
FROM pay_order
WHERE `status` = 1 AND created_at BETWEEN ? AND ?";

        $bindings = [$payTimeBegin, $payTimeEnd];

        if (!empty($gameAreas)) {
            MyLog::info("如果不为空传入的渠道" . json_encode($gameAreas));

            $query .= " AND game_area IN (" . implode(',', $gameAreaPlaceholders) . ")";
            $bindings = array_merge($bindings, $gameAreas);
        }
        if (in_array('qqgame', $type)) {
            $channelPlaceholders = ['?'];
            $channels=['qq'];
        }
        else {
            $channelPlaceholders = array_fill(0, count($channels), '?');
        }
        MyLog::info('渠道汇总'.json_encode($channelPlaceholders));
        MyLog::info('渠道汇总'.json_encode($channels));

        if($groups_ids && in_array('qqgame', $type)){
            $query .= " AND SUBSTRING_INDEX(order_no, '_', 1) IN (" . implode(',', $channelPlaceholders) . ")";
            $bindings = array_merge($bindings, $channels);
        }else{
            if (!empty($channel)) {
                $query .= " AND SUBSTRING_INDEX(order_no, '_', 1) IN (" . implode(',', $channelPlaceholders) . ")";
                $bindings = array_merge($bindings, $channels);
            }
        }

        $query .= " GROUP BY date, category";
        MyLog::info('SQL語句'.json_encode($query));

        $result = DB::select($query, $bindings);
        foreach ($result as $row) {
            $date = $row->date;
            if (!isset($sumData[$date])) {
                // 如果日期还没有在求和数据中出现过，则将当前行的数据作为初始值
                $sumData[$date] = [
                    'fee' => $row->fee,
                    'front_fee' => $row->front_fee,
                    'Dvalue' => $row->Dvalue
                ];
            } else {
                // 如果日期已经在求和数据中出现过，则将当前行的值与已存在的值进行求和
                $sumData[$date]['fee'] += $row->fee;
                $sumData[$date]['front_fee'] += $row->front_fee;
                $sumData[$date]['Dvalue'] += $row->Dvalue;
            }
        }

        // 将合计值添加到每条数据中
        foreach ($result as $row) {
            $date = $row->date;
            $row->total_fee = $sumData[$date]['fee'];
            $row->total_front_fee = $sumData[$date]['front_fee'];
            $row->total_Dvalue = $sumData[$date]['Dvalue'];
        }

        // 补齐日期：对无数据的日期生成0值记录
        try {
            $startDay = \Carbon\Carbon::parse($payTimeBegin)->startOfDay();
            $endDay = \Carbon\Carbon::parse($payTimeEnd)->startOfDay();
            $existingDates = array_fill_keys(array_keys($sumData ?? []), true);

            for ($day = $startDay->copy(); $day->lte($endDay); $day->addDay()) {
                $dateStr = $day->format('Y-m-d');
                if (!isset($existingDates[$dateStr])) {
                    $zero = new \stdClass();
                    $zero->date = $dateStr;
                    $zero->category = '';
                    $zero->fee = 0;
                    $zero->front_fee = 0;
                    $zero->Dvalue = 0;
                    $zero->total_fee = 0;
                    $zero->total_front_fee = 0;
                    $zero->total_Dvalue = 0;
                    $result[] = $zero;
                }
            }

            // 按日期、类别排序，保证输出稳定
            usort($result, function($a, $b) {
                $ad = $a->date <=> $b->date;
                if ($ad !== 0) return $ad;
                return strcmp((string)$a->category, (string)$b->category);
            });
        } catch (\Exception $e) {
            // 忽略补齐异常，返回已有结果
        }


        return  ResponseUtil::success($result);
    }

// 充值排行
    public function top()
    {
        $customerId = request()->get('customerId');
        $roleId = request()->get('roleId');
        $gameArea = request()->get('gameArea');
        $createTimeBegin = request()->get('createTimeBegin');
        $createTimeEnd = request()->get('createTimeEnd');

        // 获取分页的支付订单
        $query = PayOrder::select('role_id', DB::raw('SUM(fee) as sumfee'), 'customer_id', 'game_area',DB::raw('COUNT(*) as paycounts'))
            ->where('status', 1)
            ->where('push_status', 1);

        // 添加时间范围条件
        if ($createTimeBegin) {
            $query->where('created_at', '>=', $createTimeBegin);
        }
        if ($createTimeEnd) {
            $query->where('created_at', '<=', $createTimeEnd);
        }

        // 添加角色 ID 和账号 ID 条件
        if ($roleId) {
            $query->where('role_id', $roleId);
        }
        if ($customerId) {
            $query->where('customer_id', $customerId);
        }
        if ($gameArea) {
            $query->where('game_area', $gameArea);
        }

        // 分组和排序
        $results = $query
            ->groupBy('role_id', 'customer_id', 'game_area')
            ->orderBy('sumfee', 'DESC')
            ->get();

        $res = [];
        // 遍历每个订单根据 role_id 查询用户信息
        foreach ($results as $order) {
                $roleID = $order->role_id;
            try {
                global $gameArea;
                $gameArea=$order->game_area;
                $userinfo = UserRole::query()->where('id', $roleID)->first();
                $order['nick'] = $userinfo->nick;
            } catch (\Exception $e) {
                // 记录错误并跳过当前 serverId
                MyLog::info('充值排行连接失败，跳过服务器ID: ' . json_encode($gameArea) . ' 错误信息: ' . $e->getMessage());
                continue; // 跳过到下一个 serverId
            }


        }

        $res['code'] = 0;
        $res['count'] = $results->count(); // 修改为 count() 方法
        $res['data'] = $results; // 修改为 count() 方法

        return ResponseUtil::json($res);
    }
    public function actPaginate() {
        $DTO = new PayOrderDTO(request()->all());

        $gameArea = $DTO->getGameArea();
        $gameAreas = $DTO->getGameAreas();
        $createDateTimeBegin = $DTO->getCreateDateTimeBegin();
        $createDateTimeEnd = $DTO->getCreateDateTimeEnd();

        // 获取支付订单记录
        $model = PayOrder::query();
        $model->where('status', 1)->where('push_status', 1); // 只选择支付成功的订单

//        if ($createDateTimeBegin) {
//            $model->where("created_at", ">=", Carbon::parse($createDateTimeBegin));
//        }
//        if ($createDateTimeEnd) {
//            $model->where("created_at", "<=", Carbon::parse($createDateTimeEnd));
//        }
        if ($gameArea !== null) {
            $model->where('game_area', $gameArea);
        }
        if ($gameAreas !== null) {
            $model->whereIn('game_area', $gameAreas);
        }

        $orders = $model->orderBy('updated_at')->get();
        $roleIds = $orders->pluck('role_id')->unique(); // 获取所有符合条件的 role_id

        // 查询 UserRole 表，获取对应的用户角色信息
        $userRoles = UserRole::whereIn('id', $roleIds)->get()->keyBy('id');

        // 统计时间分布（按用户ID去重计数）
        $timeDistribution = [
            'firstPayment' => array_fill_keys(['0-10', '10-30', '30-60', '60-360', '360+'], []),
            'secondToFirstInterval' => array_fill_keys(['0-10', '10-30', '30-60', '60-360', '360+'], []),
            'thirdToSecondInterval' => array_fill_keys(['0-10', '10-30', '30-60', '60-360', '360+'], []),
        ];

        // 统计首次付费金额分布
        $amountDistribution = [
            '1-10' => 0,
            '11-50' => 0,
            '51-100' => 0,
            '101-500' => 0,
            '500+' => 0,
        ];

        // 存储首次付费记录
        $firstPayments = [];
        $seenAmounts = []; // 用于跟踪已统计的金额

        foreach ($orders as $order) {
            $customerId = $order->role_id;
            $updatedAt = Carbon::parse($order->updated_at); // 确保是 Carbon 实例

            // 确保用户角色存在
            if (!isset($userRoles[$customerId])) {
                continue; // 如果没有对应的用户角色，跳过
            }

            $userRole = $userRoles[$customerId];

            // 记录每个玩家的支付时间，并在首次出现时统计首充时间段（按用户去重）
            if (!isset($firstPayments[$customerId])) {
                $createTime = Carbon::parse($userRole->create_time); // 获取用户角色的创建时间
                $timeDiff = $updatedAt->diffInMinutes($createTime);
                $firstInterval = $this->getTimeInterval($timeDiff);
                if ($firstInterval) {
                    $timeDistribution['firstPayment'][$firstInterval][$customerId] = true;
                }
                $firstPayments[$customerId] = [
                    'paymentTimes' => [$updatedAt], // 第一次付费时间
                ];
            } else {
                $firstPayments[$customerId]['paymentTimes'][] = $updatedAt; // 记录后续付费时间
            }

            // 统计首次付费金额分布，确保每个金额只统计一次
            $firstPaymentAmount = $order->fee;
            $amountKey = '';

            if ($firstPaymentAmount >= 1 && $firstPaymentAmount <= 10) {
                $amountKey = '1-10';
            } elseif ($firstPaymentAmount >= 11 && $firstPaymentAmount <= 50) {
                $amountKey = '11-50';
            } elseif ($firstPaymentAmount >= 51 && $firstPaymentAmount <= 100) {
                $amountKey = '51-100';
            } elseif ($firstPaymentAmount >= 101 && $firstPaymentAmount <= 500) {
                $amountKey = '101-500';
            } elseif ($firstPaymentAmount > 500) {
                $amountKey = '500+';
            }

            // 检查是否已经统计过该用户的该金额
            if ($amountKey && !isset($seenAmounts[$customerId][$amountKey])) {
                $amountDistribution[$amountKey]++;
                $seenAmounts[$customerId][$amountKey] = true; // 标记该金额已统计
            }

            // 支付时间记录已在上方处理（避免重复）
        }

        // 计算二充到首充时间和三充到二充时间
        foreach ($firstPayments as $customerId => $paymentData) {
            $paymentTimes = $paymentData['paymentTimes'];

            if (count($paymentTimes) > 1) {
                // 计算二充到首充时间
                $secondToFirstInterval = $paymentTimes[1]->diffInMinutes($paymentTimes[0]);
                $secondInterval = $this->getTimeInterval($secondToFirstInterval);
                if ($secondInterval) {
                    $timeDistribution['secondToFirstInterval'][$secondInterval][$customerId] = true;
                }
            }

            if (count($paymentTimes) > 2) {
                // 计算三充到二充时间
                $thirdToSecondInterval = $paymentTimes[2]->diffInMinutes($paymentTimes[1]);
                $thirdInterval = $this->getTimeInterval($thirdToSecondInterval);
                if ($thirdInterval) {
                    $timeDistribution['thirdToSecondInterval'][$thirdInterval][$customerId] = true;
                }
            }
        }

        // 计算占比
        $totalPlayers = UserRole::query()->count(); // 获取总玩家数
        foreach ($timeDistribution as &$distribution) {
            foreach ($distribution as $key => $value) {
                $uniqueCount = is_array($value) ? count($value) : (int)$value;
                $distribution[$key] = [
                    'count' => $uniqueCount,
                    'percentage' => $totalPlayers > 0 ? round(($uniqueCount / $totalPlayers) * 100, 2) : 0,
                ];
            }
        }

        foreach ($amountDistribution as $key => $count) {
            $amountDistribution[$key] = [
                'count' => $count,
                'percentage' => $totalPlayers > 0 ? round(($count / $totalPlayers) * 100, 2) : 0,
            ];
        }

        return [
            'code' => 0,
            'timeDistribution' => $timeDistribution,
            'amountDistribution' => $amountDistribution,
        ];
    }

    private function getTimeInterval($minutes) {
        if ($minutes <= 10) {
            return '0-10';
        } elseif ($minutes <= 30) {
            return '10-30';
        } elseif ($minutes <= 60) {
            return '30-60';
        } elseif ($minutes <= 360) {
            return '60-360';
        } else {
            return '360+';
        }
    }



    public function gameMall()
    {
        $roleId = request()->get('roleId');
        $gameArea = request()->get('gameArea');
        $createTimeBegin = request()->get('createTimeBegin');
        $createTimeEnd = request()->get('createTimeEnd');
        $opTypes = request()->get('opTypes');


        // 获取分页的支付订单
        $query = GameMallGoods::select(
            'goodsid',
            'goodsname',
            'moneyvalue',
            \DB::raw('SUM(moneyvalue) as total_money'),
            \DB::raw('SUM(count) as total_count'),
        );

        // 添加时间范围条件
        if ($createTimeBegin) {
            $query->where('buytime', '>=', $createTimeBegin);
        }
        if ($createTimeEnd) {
            $query->where('buytime', '<=', $createTimeEnd);
        }
        if ($opTypes) {
            $opTypes = explode(',',$opTypes);
            foreach($opTypes as &$opType){
                $opType = (int)$opType;
            }
            $query->whereIn('goodsid', $opTypes);
        }

        // 添加角色 ID 和账号 ID 条件
        if ($roleId) {
            $query->where('roleid', $roleId);
        }



        // 分组和排序
        $results = $query
            ->groupBy('goodsid', 'goodsname','moneyvalue')
            ->get();

        // 更新 serverid 为传入的 gameArea 值
        $results = GameMallGoods::updateServerIdInResults($results, $gameArea);

        $res = [];
        $res['code'] = 0;
        $res['count'] = $results->count();
        $res['data'] = $results;

        return ResponseUtil::json($res);
    }

    //付费转化
    public function payTransform()
    {
        $DTO = new PayOrderDTO(request()->all());

        $gameArea = $DTO->getGameArea();
        $createDateTimeBegin = $DTO->getCreateDateTimeBegin();
        $createDateTimeEnd = $DTO->getCreateDateTimeEnd();

        // 获取日期范围
        $dates = [];
        if ($createDateTimeBegin && $createDateTimeEnd) {
            $startDate = Carbon::parse($createDateTimeBegin);
            $endDate = Carbon::parse($createDateTimeEnd);
            $dates = [];
            for ($date = $startDate->copy(); $date->lte($endDate); $date->addDay()) {
                $dates[] = $date->copy();
            }
        } else {
            $dates = [Carbon::today()];
        }

        $result = [];
        foreach ($dates as $date) {
            $dateString = $date->format('Y-m-d');
            $dayRange = [
                $date->startOfDay()->format('Y-m-d H:i:s'),
                $date->endOfDay()->format('Y-m-d H:i:s')
            ];
            // 查询当天注册的用户
            $roleIds = Customer::whereBetween('created_at', $dayRange)->pluck('id');
            MyLog::info(json_encode($dayRange).'当前注册的人数'.json_encode($roleIds));
            // 查询当天的订单数据，针对 role_id 去重
            $dayPayCount = PayOrder::where('status', 1)
                ->where('push_status',1)
                ->whereBetween('created_at', $dayRange)
                ->where('game_area', $gameArea)
                ->wherein('customer_id',$roleIds)
                ->distinct('customer_id')
                ->count('customer_id');
            MyLog::info('当天订单数据'.json_encode($dayPayCount));

            //日付费玩家(历史)
            $dayuserPayCount = PayOrder::where('status', 1)
                ->where('push_status',1)
                ->whereBetween('created_at', $dayRange)
                ->where('game_area', $gameArea)
                ->distinct('customer_id')
                ->count('customer_id');
            //日活跃玩家(历史)
            $Dayuser = Customer::whereBetween('logindata', $dayRange) ->count();


            //日费率
            $DayPaylv=$Dayuser > 0 ? ($dayuserPayCount / $Dayuser) * 100 : 0;


            // 新增用户数量
            $newUserCount = $roleIds->count();

            // 计算付费率
            $dayPayRate = $newUserCount > 0 ? ($dayPayCount / $newUserCount) * 100 : 0;

            // 针对当前日期的，往后推7天和30天
            $weekRange = [
                $date->copy()->startOfDay()->format('Y-m-d H:i:s'),
                $date->copy()->addDays(7)->endOfDay()->format('Y-m-d H:i:s')
            ];
            $monthRange = [
                $date->copy()->startOfDay()->format('Y-m-d H:i:s'),
                $date->copy()->addDays(30)->endOfDay()->format('Y-m-d H:i:s')
            ];
            $weekRangetimetamp = [$date->copy()->addDays(0)->timestamp, $date->copy()->addDays(7)->timestamp];
            $monthRangetimetamp = [$date->copy()->addDays(0)->timestamp, $date->copy()->addDays(30)->timestamp];


            $weekNewUsers = Customer::whereBetween('created_at', $weekRange)
                ->pluck('id');
            $weekNewUserCount=$weekNewUsers->count();

            // 计算周数据
            $weekPayCount = PayOrder::where('status', 1)
                ->where('push_status',1)
                ->whereBetween('created_at', $weekRange)
                ->where('game_area', $gameArea)
                ->wherein('customer_id',$weekNewUsers)
                ->distinct('customer_id')
                ->count('customer_id');
            MyLog::info('当天订单数据'.json_encode($weekPayCount));

            MyLog::info(json_encode($weekRange).'当周注册的人数'.json_encode($roleIds));
            $weekPayRate = $weekNewUserCount > 0 ? ($weekPayCount / $weekNewUserCount) * 100 : 0;

            //历史
            $weekuserPayCount = PayOrder::where('status', 1)
                ->where('push_status',1)
                ->whereBetween('created_at', $weekRange)
                ->where('game_area', $gameArea)
                ->distinct('customer_id')
                ->count('customer_id');

            //月活跃玩家
            $weekNewUserCount = Customer::whereBetween('logindata', $monthRange)
                ->count();
            //月付费率
            $WeekPaylv = $weekNewUserCount > 0 ? ($weekuserPayCount / $weekNewUserCount) * 100 : 0;


            $monthNewUsers= Customer::whereBetween('created_at', $monthRange)
                ->pluck('id');
            // 计算月数据
            $monthPayCount = PayOrder::where('status', 1)
                ->where('push_status',1)
                ->whereBetween('created_at', $monthRange)
                ->where('game_area', $gameArea)
                ->wherein('customer_id',$monthNewUsers)
                ->distinct('role_id')
                ->count('role_id');
            MyLog::info('当天订单数据'.json_encode($monthPayCount));

            $monthNewUserCount=$monthNewUsers->count();
            MyLog::info(json_encode($monthRange).'当月注册的人数'.json_encode($roleIds));

            $monthPayRate = $monthNewUserCount > 0 ? ($monthPayCount / $monthNewUserCount) * 100 : 0;

            //历史
            $monthuserPayCount = PayOrder::where('status', 1)
                ->where('push_status',1)
                ->whereBetween('created_at', $monthRange)
                ->where('game_area', $gameArea)
                ->distinct('customer_id')
                ->count('customer_id');

            //月活跃玩家
            $monthNewUserCount = Customer::whereBetween('logindata', $monthRange)
                ->count();
            //月付费率
            $monthPaylv = $monthuserPayCount > 0 ? ( $monthuserPayCount/ $monthNewUserCount) * 100 : 0;


            // 构建结果数组
            $result[] = [
                'date' => $dateString,
                'dayPayCount' => $dayPayCount,
                'dayPayRate' => round($dayPayRate, 2) . '%',
                'weekPayCount' => $weekPayCount,
                'weekPayRate' => round($weekPayRate, 2) . '%',
                'monthPayCount' => $monthPayCount,
                'monthPayRate' => round($monthPayRate, 2) . '%',
                'dayPaylv'=>round($DayPaylv, 2) . '%',
                'WeekPaylv'=>round($WeekPaylv, 2) . '%',
                'monthPaylv'=>round($monthPaylv, 2) . '%'

            ];
        }
        $totalDayPaylv = $totalWeekPaylv = $totalMonthPaylv = 0;
        $count = count($result);

        foreach ($result as $res) {
            $totalDayPaylv += floatval(rtrim($res['dayPaylv'], '%'));
            $totalWeekPaylv += floatval(rtrim($res['WeekPaylv'], '%'));
            $totalMonthPaylv += floatval(rtrim($res['monthPaylv'], '%'));
        }
        MyLog::info('$totalDayPaylv'.json_encode($totalDayPaylv));
        MyLog::info('$totalWeekPaylv'.json_encode($totalWeekPaylv));
        MyLog::info('$totalWeekPaylv'.json_encode($totalMonthPaylv));
        MyLog::info('$count'.json_encode($count));

        $averageDayPaylv = $count > 0 ? round($totalDayPaylv / $count, 2) . '%' : 0;
        $averageWeekPaylv = $count > 0 ? round($totalWeekPaylv / $count , 2) . '%' : 0;
        $averageMonthPaylv = $count > 0 ? round($totalMonthPaylv / $count, 2) . '%' : 0;



        $res=[];
        $res['total']=count($result);
        $res['averageDayPaylv']=$averageDayPaylv;
        $res['averageWeekPaylv']=$averageWeekPaylv;
        $res['averageMonthPaylv']=$averageMonthPaylv;

        $res['data']=$result;

        return ResponseUtil::success($res);
    }


    //付费数据
    public function payOrderData()
    {
        $DTO = new PayOrderDTO(request()->all());

        $gameArea = $DTO->getGameArea();
        $createDateTimeBegin = $DTO->getCreateDateTimeBegin();
        $createDateTimeEnd = $DTO->getCreateDateTimeEnd();

        // 获取日期范围
        $dates = [];
        if ($createDateTimeBegin && $createDateTimeEnd) {
            $startDate = Carbon::parse($createDateTimeBegin);
            $endDate = Carbon::parse($createDateTimeEnd);
            for ($date = $startDate->copy(); $date->lte($endDate); $date->addDay()) {
                $dates[] = $date->copy();
            }
        } else {
            $dates = [Carbon::today()];
        }

        $result = [];
        $totalActiveUserFee = 0; // 活跃玩家充值金额总额
        $totalFirstPayFee = 0; // 首日付费玩家充值金额
        $totalFirstPayPlayersFee = 0; // 首次付费玩家充值金额
        foreach ($dates as $date) {
            $dateString = $date->format('Y-m-d');
            $dayRange = [
                $date->startOfDay()->format('Y-m-d H:i:s'),
                $date->endOfDay()->format('Y-m-d H:i:s')
            ];

            // 查询当天注册的用户
            $newUsers = Customer::whereBetween('logindata', $dayRange)->pluck('id');

            // 查询当天活跃玩家
            $hotUsers = Customer::whereBetween('created_at', $dayRange)->pluck('id');

            // 活跃玩家充值数据
            $dayPayData = PayOrder::where('status', 1)
                ->whereBetween('created_at', $dayRange)
                ->where('game_area', $gameArea);

            // 计算活跃玩家的付费金额总额、付费人数、付费次数
            $hotUserTotalFee = $dayPayData->sum('fee');
            $hotUserPayCount = $dayPayData->count();
            $hotUserDistinctCount = $dayPayData->distinct('customer_id')->count('customer_id');

            // 查询当天注册的玩家的充值数据
            $dayNewUserPayData = PayOrder::where('status', 1)
                ->whereBetween('created_at', $dayRange)
                ->whereIn('customer_id', $newUsers)
                ->where('game_area', $gameArea);

            // 计算首日付费玩家的付费金额总额、付费人数、付费次数
            $firstPayTotalFee = $dayNewUserPayData->sum('fee');
            $firstPayCount = $dayNewUserPayData->count();
            $firstDistinctCount = $dayNewUserPayData->distinct('customer_id')->count('customer_id');

            // 查询首次付费玩家
            $firstPayPlayers = Customer::whereNotIn('id', function($query) use ($dayRange) {
                $query->select('customer_id')
                    ->from('pay_order')
                    ->where('status', 1)
                    ->where('created_at', '<', $dayRange[0]); // 当前日期之前没有支付过的玩家
            })->pluck('id');

            // 计算首次付费玩家的付费金额总额、付费人数、付费次数
            $firstPayPlayersData = PayOrder::where('status', 1)
                ->whereIn('customer_id', $firstPayPlayers)
                ->where('game_area', $gameArea);

            $firstPayPlayersTotalFee = $firstPayPlayersData->sum('fee');
            $firstPayPlayersCount = $firstPayPlayersData->count();
            $firstPayPlayersDistinctCount = $firstPayPlayersData->distinct('customer_id')->count('customer_id');
            // 更新总金额
            $totalActiveUserFee += $hotUserTotalFee;
            $totalFirstPayFee += $firstPayTotalFee;
            $totalFirstPayPlayersFee += $firstPayPlayersTotalFee;
            // 构建结果数组
            $result[] = [
                'date' => $dateString,
                'hotUserTotalFee' => $hotUserTotalFee,
                'hotUserDistinctCount' => $hotUserDistinctCount,
                'hotUserPayCount' => $hotUserPayCount,
                'firstPayTotalFee' => $firstPayTotalFee,
                'firstPayDistinctCount' => $firstDistinctCount,
                'firstPayCount' => $firstPayCount,
                'firstPayPlayersTotalFee' => $firstPayPlayersTotalFee,
                'firstPayPlayersDistinctCount' => $firstPayPlayersDistinctCount,
                'firstPayPlayersCount' => $firstPayPlayersCount,
            ];
        }
        // 最终结果
        $res['total'] = count($result);
        $res['totalActiveUserFee'] = $totalActiveUserFee;
        $res['totalFirstPayFee'] = $totalFirstPayFee;
        $res['totalFirstPayPlayersFee'] = $totalFirstPayPlayersFee;
        $res['data'] = $result;

        return ResponseUtil::success($res);
    }


        //订单分类统计
    public function orders()
    {

        $payOrderSearchDTO = new PayOrderDTO(request()->all());

        $data = $this->payOrderService->ordersPaginate($payOrderSearchDTO);

        $res = [];
        $res['code'] = 0;
        $res['count'] =  count($data);
        $res['data'] =  $data;
        return ResponseUtil::json($res);
    }

}
